package com.yihaodian.search.grouping;

import java.util.ArrayList;
import java.util.List;
import java.util.PriorityQueue;

import com.yihaodian.api.search.grouping.GroupingResult;

public class GroupingMerger {
	public static GroupingResult[] merge(List<GroupingResult[]> resultsList){
		PriorityQueue<GroupElement> queue = 
			new PriorityQueue<GroupElement>();
		for (GroupingResult[] results : resultsList) {
			if (results != null) {
				GroupElement e = new GroupElement(results);
				queue.add(e);
			}
		}
		
		List<GroupingResult> nodes = new ArrayList<GroupingResult>();
		
		/**
		 * Groups merge.
		 */
		int max = 10; // for test
		int mergeNodeCount = 0;
		GroupingResult lastNode = null;
		while (mergeNodeCount <= max && queue.peek() != null) {
			GroupElement e = queue.poll();
			GroupingResult currentNode = e.node;
			if (lastNode != null && 
					currentNode.getGroupName().compareTo(lastNode.getGroupName())==0) {
				/**
				 * Hits merge
				 */
				lastNode.setHits(HitMerger.merge(lastNode.getHits(), currentNode.getHits()));
			} else {
				 if (lastNode != null) {
					 mergeNodeCount++;
					 nodes.add(lastNode);
				 }
				 lastNode = currentNode;
			}
			
			/**
			 * Get the next grouping result,  put it to priority queue
			 * for re-comparing.
			 */
			if (e.next()) {
				queue.add(e);
			}
		}
		
		if (lastNode != null) {
			nodes.add(lastNode);
		}
		
		return nodes.toArray(new GroupingResult[0]);
	}
	
	static class GroupElement implements Comparable<GroupElement> {
		GroupingResult[] groupResults = null;;

		GroupingResult node = null;
		int idx = 0;
		int size = 0;

		GroupElement(GroupingResult[] groupResults) {
			this.groupResults = groupResults;

			this.size = groupResults.length;
			this.node = groupResults[idx];
		}

		public boolean next() {
			idx++;
			if (idx >= size)
				return false;

			this.node = groupResults[idx];
			return true;
		}

		@Override
		public int compareTo(GroupElement o) {
			return node.getGroupName().compareTo(o.node.getGroupName());
		}
	}

}
